package bg.btanev.eightyfour.repository.impl;

import java.util.List;

import org.apache.commons.lang.Validate;
import org.hibernate.Criteria;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import bg.btanev.eightyfour.dao.GenericDAO;
import bg.btanev.eightyfour.domain.Tag;
import bg.btanev.eightyfour.domain.Target;
import bg.btanev.eightyfour.repository.TagRepository;

/**
 *
 * @author B.Tanev
 *
 */
public class TagRepositoryImpl implements TagRepository {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = LoggerFactory.getLogger(TagRepositoryImpl.class);

	private GenericDAO<String, Tag> tagDAO;

	public TagRepositoryImpl() {
	}

	public void setTagDAO(GenericDAO<String, Tag> tagDAO) {
		this.tagDAO = tagDAO;
	}

	@Override
	public Tag getTag(String name) {
		name = Tag.validateAndNormalizeName(name);

		Tag tag = tagDAO.findById(name);
		if (tag == null) {
			tag = new Tag(name);
			tagDAO.saveUpdateEntity(tag);
		}

		return tag;
	}

	@Override
	public List<Tag> findTagsForTarget(Target target) {
		logger.debug("findTagsForTarget(Target) - start"); //$NON-NLS-1$

		Validate.notNull(target);

		DetachedCriteria detachedCriteria = tagDAO.createDetachedCriteria();

		DetachedCriteria profileEventCriteria = detachedCriteria.createCriteria("profileEvent");
		profileEventCriteria.createAlias("profile", "pe", Criteria.LEFT_JOIN);
		profileEventCriteria.add(Restrictions.eq("pe.target", target));

		detachedCriteria.addOrder(Order.asc("id"));
		detachedCriteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);

		List<Tag> result = tagDAO.findByCriteria(detachedCriteria);

		logger.debug("findTagsForTarget(Target) - end"); //$NON-NLS-1$
		return result;
	}
}
